package com.galudisu.handsonic.base;

import com.galudisu.handsonic.base.utils.DateUtils;
import com.galudisu.handsonic.base.utils.validators.BeanValidators;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;

/**
 * @author barudisshu
 */
public abstract class BaseController {

    @Resource
    private Validator validator;

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Server Validator Bean
     *
     * @param model  : Model
     * @param object : Object
     * @param groups : Groups
     * @return : True / False
     */
    protected boolean beanValidators(Model model, Object object, Class<?>... groups) {
        try {
            logger.info("validatiWithException");
            BeanValidators.validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            logger.info("ConstraintViolationExceptiont");
            ex.printStackTrace();
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            list.add(0, "Validator failure: ");
            return false;
        }
        return true;
    }

    protected String beanValidators(Object object, Class<?>... groups) {
        String error = "";
        try {
            BeanValidators.validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            list.add(0, "Validator failure: ");
            error = list.toString();
        }
        return error;
    }

    /**
     * Server Validator Bean Groups
     *
     * @param redirectAttributes : Attributes
     * @param object             : Object
     * @param groups             : Groups
     * @return : True / False
     */
    protected boolean beanValidators(RedirectAttributes redirectAttributes, Object object, Class<?>... groups) {
        try {
            BeanValidators.validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            list.add(0, "Validator failure: ");
            return false;
        }
        return true;
    }


    /**
     * Init data binding
     *
     * @param binder   : binder
     * @param request  : request
     * @param response : response
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder, HttpServletRequest request, HttpServletResponse response) {
        binder.registerCustomEditor(String.class, new PropertyEditorSupport() {

            @Override
            public void setAsText(String text) {
                setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
            }

            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? value.toString() : "";
            }
        });
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {

            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? (DateUtils.format((Date) value, DateUtils.YYYY_MM_DD)) : "";
            }

            @Override
            public void setAsText(String text) {
                if (StringUtils.isNotEmpty(text) && text.length() <= 5) {
                    setValue(DateUtils.formatTimeNoSs(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 8) {
                    setValue(DateUtils.formatTime(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 10) {
                    setValue(DateUtils.formatNoTime(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 16) {
                    setValue(DateUtils.formatWithHHmm(text));
                } else if (StringUtils.isNotEmpty(text)) {
                    setValue(DateUtils.format(text));
                }
            }
        });
    }

}
